Skip to content

PHSimpleVertexFinder INTT requirements#4248

Merged
osbornjd merged 13 commits into
sPHENIX-Collaboration:masterfrom
cdean-github:master
Apr 29, 2026
Merged

PHSimpleVertexFinder INTT requirements#4248
osbornjd merged 13 commits into
sPHENIX-Collaboration:masterfrom
cdean-github:master

Conversation

@cdean-github
Copy link
Copy Markdown
Contributor

@cdean-github cdean-github commented Apr 15, 2026

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work for users)
  • Requiring change in macros repository (Please provide links to the macros pull request in the last section)
  • I am a member of GitHub organization of sPHENIX Collaboration, EIC, or ECCE (contact Chris Pinkenburg to join)

What kind of change does this PR introduce? (Bug fix, feature, ...)

I added the ability to require INTT clusters on a track when making primary vertices. The code defaults to not requiring this, and when enabled the default is a single cluster

  void setRequireINTT(bool set) { _require_intt = set; }
  void setNinttRequired(unsigned int n) { _nintt_required = n; }

and

  bool _require_mvtx = true;
  bool _require_intt = false;
  unsigned int _nmvtx_required = 2;
  unsigned int _nintt_required = 1;

I also patched a small bug in DecayFinder which would veto events if one candidate passed the trigger but another failed

Lastly, I cleaned up some KFParticle code. Its only cosmetic

TODOs (if applicable)

Links to other PRs in macros and calibration repositories (if applicable)

Motivation / Context
Add optional INTT-cluster requirements to the primary-vertex finder so vertexing can require both MVTX and INTT silicon clusters on tracks. Preserve default behavior (backwards compatible) while enabling tighter track/vertex selection when INTT information is desired. Also fix a DecayFinder logic bug that could incorrectly veto events, adjust HFTrackEfficiency seed counting, and add verbosity/diagnostic cleanups in KFParticle code.

Key changes

  • PHSimpleVertexFinder
    • New public API: setRequireINTT(bool set = true), setNinttRequired(unsigned int n)
    • New config/state: _require_intt (default false), _nintt_required (default 1)
    • Centralized cluster gating via passClusterRequirement(SvtxTrack*, const std::string& type = "MVTX")
    • Default arguments added for setRequireMVTX, zeroField, set_pp_mode
    • Behavior: when _require_intt enabled, tracks must meet the configured INTT cluster count (default 1) to be used for vertexing
  • DecayFinder
    • findDecay() return type changed bool → int (returns count of reconstructable candidates)
    • Fix: per-candidate flags are reset each loop and HepMC-missing events continue to next candidate; event trigger/abort logic uses candidate count to avoid vetoing when at least one candidate is valid
  • HFTrackEfficiency
    • Seed-counting now iterates SvtxTrackState entries instead of using TrackSeed::size_cluster_keys(); m_reco_track_silicon_seeds and m_reco_track_tpc_seeds default/unfilled values changed from 0 to -1
  • KFParticle modules
    • Added verbosity-gated diagnostic printing and helper printSelectionCheck()
    • Minor API change: removed const from findTwoProngs()
    • TTree branch renames for BCO timing: Collision_BCO, GL1_BCO, last_GL1_BCO
    • Minor reordering and logging adjustments in event processing

Potential risk areas

  • Reconstruction behavior: Enabling _require_intt changes track acceptance and vertexing results — validate physics and efficiency impacts before enabling in production.
  • HFTrackEfficiency outputs: New seed-counting logic and defaulting to -1 can change QA/NTuple values and downstream analyses; verify ROOT outputs and comparisons to previous baseline.
  • API/ABI: DecayFinder findDecay() return-type change requires that all callers be updated; missing updates could cause build/runtime issues.
  • IO/NTuple compatibility: Branch renames (BCO → Collision_BCO/GL1_BCO/last_GL1_BCO) will break scripts expecting old names.
  • Performance & thread-safety: Iterating SvtxTrackState for seed counts and added diagnostic logging may affect hot paths or multi-threaded contexts; profile and audit for contention/regressions.
  • Logging/verbosity: Added verbose diagnostics are gated but may still produce heavy output at high verbosity—ensure not enabled in production workflows.

Possible future improvements

  • Surface MVTX/INTT cluster requirements in central reconstruction configuration and documentation for consistent workflows.
  • Add unit/integration tests for vertexing with/without INTT requirements, DecayFinder candidate-counting, and HFTrackEfficiency seed-count consistency.
  • Provide an optimized seed-counting path (or cache) if profiling shows regressions from state iteration.
  • Consolidate verbosity/diagnostic controls across KFParticle modules into a common logger or configuration.

Caveat
AI-generated summaries can be mistaken. Review the diffs and run targeted tests to confirm behavior before merging.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 15, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b4fd3ce3-6781-436a-a728-f94c770533a8

📥 Commits

Reviewing files that changed from the base of the PR and between ad8c400 and 0915026.

📒 Files selected for processing (2)
  • offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc
  • offline/packages/trackreco/PHSimpleVertexFinder.cc
🚧 Files skipped from review as they are similar to previous changes (1)
  • offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc

📝 Walkthrough

Walkthrough

This PR adds verbosity-gated diagnostics across KFParticle code, refactors MVTX/INTT cluster checks into a shared helper, renames BCO branches in nTuples, changes DecayFinder::findDecay to return an integer count, and changes HFTrackEfficiency to compute per-daughter seed counts by iterating SvtxTrackState (seed counters default to -1).

Changes

Cohort / File(s) Summary
HFTrackEfficiency seed counting
offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc
Replaced seed-container-derived counts with per-track iteration over SvtxTrackStates: skip pathlength==0, ignore CLUSKEYMAX, map tracker IDs to MVTX/INTT/TPC and increment per-state counts. resetBranches now uses -1 as unfilled default for silicon/TPC seed counters.
KFParticle selection debugging & API
offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc, .../KFParticle_Tools.h
Added m_verbosity, color strings, three printSelectionCheck(...) overloads, and extensive verbosity-gated selection/diagnostic prints in selection/build routines; removed const from findTwoProngs; buildMother now calls GetPt(calculated_pt, calculated_pt_err).
KFParticle event reconstruction diagnostics
offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.cc
Inserted m_verbosity >= 10 gated logging to report sizes of daughterParticles, goodTrackIndex, and PV counts at several chain-building points.
KFParticle nTuple BCO branches
offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc
Renamed ROOT TTree branches: replaced event_bco/last_event_bco with GL1_BCO/last_GL1_BCO; renamed shifted BCO branch to Collision_BCO (wired to existing members).
KFParticle core: verbosity & BCO handling
offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc
Initialize m_verbosity from Verbosity() in Init(). Reordered BCO-matching earlier in process_event, adjusted verbosity levels for messages, set missing BCO fields to 0 (instead of -1), and moved the “no tracks” check after BCO handling.
DecayFinder: counting & per-candidate resets
offline/packages/decayfinder/DecayFinder.cc, .../DecayFinder.h
Changed findDecay return type boolint; function now counts reconstructable decays and returns that count. Per-mother candidate flags (aTrackFailedPT, aTrackFailedETA, aMotherHasPhoton, aMotherHasPi0) are reset per candidate; when HepMC missing, loop continues to next candidate rather than returning.
PHSimpleVertexFinder cluster requirements
offline/packages/trackreco/PHSimpleVertexFinder.cc, .../PHSimpleVertexFinder.h
Consolidated MVTX/INTT cluster gating into passClusterRequirement(SvtxTrack*, type) supporting "MVTX"/"INTT"; added API setRequireINTT and setNinttRequired; default-true arguments added to some setters; callers updated to use the helper and symmetric INTT gating applied where configured.

Sequence Diagram(s)

(omitted — changes are diagnostic, API tweaks, and internal gating; no new multi-component sequential flow requiring diagram)

Possibly related PRs


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit 5a29f035df4f3cc6c65db7e16ee999f06ec9ba33:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit ce03df27c0acf8e596f77aa98a7c294ba62a8d64:
Jenkins on fire


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit 43335a541ecaf08de52458928255436ddd5adb53:
Jenkins on fire


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit 11a9d5c35e4332b28eff3ba262e6e46eec9db3d7:
Jenkins on fire


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@cdean-github cdean-github marked this pull request as ready for review April 18, 2026 14:13
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
offline/packages/decayfinder/DecayFinder.cc (1)

455-459: ⚠️ Potential issue | 🟠 Major

Don’t zero out an accumulated decay count on a null map entry.

Line 458 returns false, which is 0 for this int function. If an earlier PHHepMCGenEventMap entry already incremented reconstructableDecayWasFound, a later null entry will still make process_event see zero and potentially abort the event.

🐛 Proposed fix
     if (!m_genevt)
     {
       std::cout << "DecayFinder: Missing node PHHepMCGenEvent" << std::endl;
-      return false;
+      continue;
     }
offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc (1)

151-186: ⚠️ Potential issue | 🟠 Major

Update BCO state before early event skips.

Because the BCO block now runs after the no-track/no-vertex returns, skipped events do not advance m_prev_event_bco. The next filled candidate can write a stale last_GL1_BCO from the previous accepted event rather than the previous GL1 event. Please hoist the BCO-state update before these early returns, or run it in each skip path before returning.

Also applies to: 188-245, 273-274

🧹 Nitpick comments (2)
offline/packages/trackreco/PHSimpleVertexFinder.h (1)

49-52: Document downstream impact for the new INTT vertex-selection API.

Please add a short compatibility note stating that defaults preserve current behavior, and whether enabling setRequireINTT(true) changes SvtxVertexMap outputs enough to require downstream validation or reprocessing.

As per coding guidelines, “If interfaces change, ask for compatibility notes and any needed downstream updates.” Based on learnings, “If the PR changes reconstruction outputs, calibration constants, or simulation behavior, ensure the description states expected analysis impact and whether reprocessing is required.”

Also applies to: 96-99

offline/packages/decayfinder/DecayFinder.cc (1)

96-103: Document the analysis impact of the changed veto semantics.

This now keeps an event when any reconstructable candidate is found, so accepted-event counts and saved DST contents can change relative to previous productions. Please state the expected analysis impact and whether existing samples require reprocessing. Based on learnings, “If the PR changes reconstruction outputs, calibration constants, or simulation behavior, ensure the description states expected analysis impact and whether reprocessing is required.”


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a20bd1d1-c22d-48cc-a032-0a680bfbe010

📥 Commits

Reviewing files that changed from the base of the PR and between 9ada433 and 51dd7c7.

📒 Files selected for processing (10)
  • offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc
  • offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc
  • offline/packages/KFParticle_sPHENIX/KFParticle_Tools.h
  • offline/packages/KFParticle_sPHENIX/KFParticle_eventReconstruction.cc
  • offline/packages/KFParticle_sPHENIX/KFParticle_nTuple.cc
  • offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc
  • offline/packages/decayfinder/DecayFinder.cc
  • offline/packages/decayfinder/DecayFinder.h
  • offline/packages/trackreco/PHSimpleVertexFinder.cc
  • offline/packages/trackreco/PHSimpleVertexFinder.h

Comment thread offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc Outdated
Comment thread offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc
Comment thread offline/packages/trackreco/PHSimpleVertexFinder.cc Outdated
cdean-github and others added 2 commits April 18, 2026 10:23
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit 51dd7c7c9e7aaefeb046e35310f7bc2c422aa9e9:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit 8921a077a2c1350a53c4f66dbcdf8bb2942efd7c:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit 04bbc4787c16b6adbd93fe0c91dba43cc3c895a7:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc (1)

381-418: ⚠️ Potential issue | 🔴 Critical

Off-by-one: seed counters are left at the -1 sentinel and then incremented, undercounting by 1.

resetBranches() now initializes m_reco_track_silicon_seeds[iTrack] and m_reco_track_tpc_seeds[iTrack] to -1 (the sentinel for "no reco track / not filled"), which is correct per the previous review. However, when a reco track is found we enter this block and start incrementing from -1, so a track with, say, 3 MVTX/INTT states ends up reporting silicon_seeds = 2 (and similarly 0 instead of 1 when only one silicon state exists, which is indistinguishable from the sentinel). The branches are written as /I, so this propagates directly into the nTuples and will bias downstream seed-count analyses.

Reset the counters to 0 once the track is confirmed, before the state loop, and keep -1 strictly as the "track not reconstructed" sentinel.

🔧 Proposed fix
       if (recoTrackFound)
       {
         selectedTracks.insert(m_dst_track);
         if (Verbosity() >= VERBOSITY_MORE)
         {
           m_dst_track->identify();
         }
         m_reco_track_exists[index] = true;
         m_reco_track_pT[index] = m_dst_track->get_pt();
         m_reco_track_eta[index] = m_dst_track->get_eta();
         m_reco_track_phi[index] = m_dst_track->get_phi();
         m_reco_track_chi2nDoF[index] = m_dst_track->get_chisq() / m_dst_track->get_ndf();
+        m_reco_track_silicon_seeds[index] = 0;
+        m_reco_track_tpc_seeds[index] = 0;

         for (auto state_iter = m_dst_track->begin_states();
         state_iter != m_dst_track->end_states();
         ++state_iter)
         {

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f2b6829d-5bca-4fa8-9f9a-c8776d8fe975

📥 Commits

Reviewing files that changed from the base of the PR and between 51dd7c7 and 5fd977d.

📒 Files selected for processing (5)
  • offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc
  • offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc
  • offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc
  • offline/packages/decayfinder/DecayFinder.cc
  • offline/packages/trackreco/PHSimpleVertexFinder.cc
🚧 Files skipped from review as they are similar to previous changes (1)
  • offline/packages/KFParticle_sPHENIX/KFParticle_Tools.cc

Comment thread offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc
Comment thread offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc
Comment thread offline/packages/trackreco/PHSimpleVertexFinder.cc Outdated
@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit 5fd977d86e0a8488a83e67ea5357b20acb3039ba:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

Copy link
Copy Markdown
Contributor

@osbornjd osbornjd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why but this PR changes the pythia QA. It doesn't seem like the performance is any different but based on the code I can't see how the vertexer performance changes. @cdean-github do you have any thoughts?

@cdean-github
Copy link
Copy Markdown
Contributor Author

I'm not sure why but this PR changes the pythia QA. It doesn't seem like the performance is any different but based on the code I can't see how the vertexer performance changes. @cdean-github do you have any thoughts?

I wonder if it's to do with what code rabbit picked up? I'm pushing changes based on its suggestions now.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
offline/packages/trackreco/PHSimpleVertexFinder.cc (1)

1266-1287: ⚠️ Potential issue | 🔴 Critical

Null-pointer dereference when a requirement is enabled with *_required == 0.

The zero-required fix isn't fully closed. With _nclus_required == 0, needs_clus is false, so the guard at L1271 is bypassed and L1276 dereferences siliconseed unconditionally. A caller such as setRequireINTT(true) + setNinttRequired(0) combined with a track that has no silicon seed will crash — this is reachable from checkDCAs (L522/540/769/787), which has no pre-check on the seed.

Secondary concern: even when siliconseed is non-null but empty (or has only clusters of the other detector type), pass stays false, so a caller using _require_X && !passClusterRequirement(...) will still veto the track despite the user asking for zero clusters.

Treating "zero required" as an automatic pass resolves both:

Proposed fix
   unsigned int nclus = 0;
-  unsigned int _nclus_required = type == "MVTX" ? _nmvtx_required : _nintt_required;
+  const unsigned int nclus_required = (type == "MVTX") ? _nmvtx_required : _nintt_required;
+
+  if (nclus_required == 0)
+  {
+    return true;
+  }
 
   TrackSeed *siliconseed = track->get_silicon_seed();
-  bool needs_clus = _nclus_required > 0;
-  if (needs_clus && !siliconseed)
+  if (!siliconseed)
   {
-    return pass;
+    return false;
   }
 
   for (auto clusit = siliconseed->begin_cluster_keys(); clusit != siliconseed->end_cluster_keys(); ++clusit)
   {
-    uint8_t trkrId = type == "MVTX" ? TrkrDefs::mvtxId : TrkrDefs::inttId;
+    const uint8_t trkrId = (type == "MVTX") ? TrkrDefs::mvtxId : TrkrDefs::inttId;
     if (TrkrDefs::getTrkrId(*clusit) == trkrId)
     {
-      nclus++;
-    }
-    if (nclus >= _nclus_required)
-    {
-      pass = true;
+      if (++nclus >= nclus_required)
+      {
+        return true;
+      }
     }
   }
+  return false;

As per coding guidelines, **/*.{cc,cpp,cxx,c} changes must prioritize correctness and memory safety.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 6db4a3e8-9885-4a3c-894c-fce268d2a237

📥 Commits

Reviewing files that changed from the base of the PR and between 5fd977d and ad8c400.

📒 Files selected for processing (3)
  • offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc
  • offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc
  • offline/packages/trackreco/PHSimpleVertexFinder.cc
🚧 Files skipped from review as they are similar to previous changes (1)
  • offline/packages/KFParticle_sPHENIX/KFParticle_sPHENIX.cc

Comment thread offline/packages/HFTrackEfficiency/HFTrackEfficiency.cc
@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit ad8c400b45eb060180c344239ba733c2e7209adf:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit 14324c07b823bca16b246db17a8ac8521caf25c7:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@cdean-github
Copy link
Copy Markdown
Contributor Author

My last commit was to fix a conflict between codeRabbit and Jenkins on what they look for (CR doesnt put braces around simple continue statements.

I checked the previous vertex QA and don't see any difference to the reference plots. KS results are 1.00
Screenshot 2026-04-23 at 9 33 33 am

@sphenix-jenkins-ci
Copy link
Copy Markdown

Build & test report

Report for commit 091502604916ed95144b085068b4ff2186689157:
Jenkins passed


Automatically generated by sPHENIX Jenkins continuous integration
sPHENIX             jenkins.io

@cdean-github
Copy link
Copy Markdown
Contributor Author

@jdosbo @pinkenburg are we OK to merge this?

@osbornjd
Copy link
Copy Markdown
Contributor

I still don't really understand why the pythia QA changes because nothing in the code should change the behavior. But the change in the QA doesn't look significant, so I think we should just merge it and reset the QA

@adfrawley
Copy link
Copy Markdown
Contributor

I agree, let's merge it now.

@osbornjd osbornjd merged commit 2f09211 into sPHENIX-Collaboration:master Apr 29, 2026
22 checks passed
@osbornjd
Copy link
Copy Markdown
Contributor

Okay, I reset the QA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants